package org.duomn.ichat.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.List;

public class FileUtil {
	
	private static final String CR = "\n";
	
	public static String concatePath(String base, String sub) {
		String basePath = base.replace("\\", "/");
		basePath = basePath.endsWith("/") ? basePath.substring(0, basePath.length() - 1) : basePath;
		
		String subPath = sub.replace("\\", "/");
		subPath = subPath.startsWith("/") ? subPath.substring(1) : subPath;
		
		// 计算需要返回多少个上级目录
		int tire = 0;
		while (subPath.startsWith("../")) { 
			subPath = subPath.substring(3);
			tire++;
		}
		// 在基础目录中返回上级目录
		while (tire != 0) {
			basePath = basePath.substring(0, basePath.lastIndexOf("/"));
			tire--;
		}
		
		return basePath + "/" + subPath;
	}

	/**
	 * 读取文件，使用文件名作参数，默认的换行符为"\n"
	 * @param file
	 * @return
	 */
	public static String readFile(String file) {
		return readFile(file, null);
	}
	
	/**
	 * 读取文件，使用文件名作参数
	 * @param file
	 * @param cr
	 * @return
	 */
	public static String readFile(String file, String cr) {
		File f = new File(file);
		return readFile(f, cr);
	}
	
	/**
	 * 读取文件，使用默认换行符"\n"
	 * @param file
	 * @return
	 */
	public static String readFile(File file) {
		return readFile(file, null);
	}

	/**
	 * 读取文件返回字符串
	 * @param file 文件
	 * @param cr 换行符
	 * @return
	 */
	public static String readFile(File file, String cr) {
		String lb = cr == null ? CR : cr;
		FileInputStream fis = null;
		BufferedReader br = null;
		StringBuilder buf = new StringBuilder();
		try {
			br = new BufferedReader(new InputStreamReader(fis = new FileInputStream(file)));
			String line = null;
			while ((line = br.readLine()) != null) {
				buf.append(line).append(lb);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
		}
		return buf.toString();
	}
	
	/**
	 * 向文件中写入多个字符串，换行符用"\n";
	 * @param output
	 * @param content
	 * @return
	 */
	public static boolean writeToFile(File output, List<String> content){
		String[] input = content.toArray(new String[content.size()]);
		return writeToFile(output, input);
	}
	
	/**
	 * 向文件中写入多个字符串，换行符用"\n"
	 * @param output
	 * @param content
	 * @return
	 */
	public static boolean writeToFile(File output, String[] content) {
		String input = StringUtil.join(content, CR);
		return writeToFile(output, input, null);
	}
	
	public static boolean writeToFile(File output, String content) {
		return writeToFile(output, content, null);
	}
	
	/**
	 * 把字符串写入文件，并用"\n" 替换掉特殊的换行符
	 * @param output
	 * @param content 字符串
	 * @param cr  字符串中指定的换行符
	 * @return
	 */
	public static boolean writeToFile(File output, String content, String cr) {
		String input = cr != null ? content.replaceAll(cr, CR) : content;
		
		if (!output.exists()) { // 如果文件不存在，检验并创建父级目录
			String dir = output.getParent();
			File dirFile = new File(dir);
			if (!dirFile.exists() || !dirFile.isDirectory()) {
				dirFile.mkdirs();
			}
		}
		
		FileOutputStream fos = null;
		BufferedWriter bw = null;
		try {
			bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output)));
			bw.write(input);
			bw.flush();
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			if(bw != null) {
				try {
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 删除文件夹
	 * @param folder
	 */
	public static void deleteFolder(File folder) {
		recursionFile(folder, new FileHandler() {
			public void handle(File f) {
				f.delete();
			}
		});
	}
	
	/**
	 * 递归目录，提供回调接口对遍历的文件和文件夹进行处理
	 * @param dir
	 * @param handle
	 */
	public static void recursionFile(File dir, FileHandler handle) {
		if (dir.isDirectory()) {
			File[] files = dir.listFiles();
			if (files != null) {
				for (File f : files) {
					recursionFile(f, handle);
				}
			}
		}
		handle.handle(dir);
	}
	
	/**
	 * 递归目录，通过FileHandler对文件进行处理
	 * @param dir
	 * @param fiter
	 * @param handle
	 */
	public static void recursionFile(File dir, FileFilter fiter, FileHandler handle) {
		if (dir.isDirectory()) {
			File[] files = dir.listFiles(fiter);
			if (files != null) {
				for (File f : files) {
					recursionFile(f, handle);
				}
			}
		}
		handle.handle(dir);
	}
	
	static interface FileHandler {
		void handle(File f);
	}
	
}
